package cn.stylefeng.guns.modular.recy.controller;
/*
 */

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.text.StrSpliter;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.stylefeng.guns.core.shiro.ShiroKit;
import cn.stylefeng.guns.core.shiro.ShiroUser;
import cn.stylefeng.guns.modular.system.entity.Dict;
import cn.stylefeng.guns.modular.system.service.DictService;
import cn.stylefeng.guns.modular.weixin.utils.WxUtils;
import cn.stylefeng.roses.core.base.controller.*;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.github.binarywang.utils.qrcode.QrcodeUtils;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.quartz.JobDataMap;
import org.springframework.stereotype.*;
import cn.stylefeng.guns.modular.recy.service.*;
import org.springframework.beans.factory.annotation.*;
import cn.stylefeng.roses.core.reqres.response.*;
import cn.stylefeng.guns.modular.recy.entity.*;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import cn.stylefeng.guns.core.common.page.*;
import com.baomidou.mybatisplus.core.metadata.*;
import com.baomidou.mybatisplus.core.conditions.*;
import cn.stylefeng.guns.modular.recy.vo.*;
import cn.stylefeng.guns.modular.recy.utils.*;
import cn.hutool.core.bean.*;

import java.util.List;
import java.util.stream.*;
import cn.stylefeng.guns.modular.recy.warpper.*;
import com.baomidou.mybatisplus.core.conditions.query.*;
import com.baomidou.mybatisplus.extension.plugins.pagination.*;
import java.util.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.ui.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;

@Controller
@RequestMapping({ "/bins" })
public class BinsController extends BaseController
{
    private String PREFIX;
    @Autowired
    private BinsService binsService;

    @Autowired
    private WasteTypeService wasteTypeService;

    @Autowired
    private WxMpService wxMpService;

    @Autowired
    private DictService dictService;

    @Autowired
    private RegionService regionService;
    
    public BinsController() {
        this.PREFIX = "/modular/recy/bins/";
    }
    
    @RequestMapping({ "" })
    public String index() {
        return this.PREFIX + "bins.html";
    }
    
    @RequestMapping({ "/add" })
    public String binsAdd() {
        return this.PREFIX + "bins_add.html";
    }
    
    @RequestMapping({ "/edit" })
    public String binsUpdate(@RequestParam("id") final String id,Model model) {
        List<WasteType> wasteTypeList = this.wasteTypeService.list();
        model.addAttribute("wasteTypeList",wasteTypeList);

        String areaName = this.getPara("areaName");
        if(StrUtil.isNotBlank(areaName)) {
            QueryWrapper<Region> regionQueryWrapper = new QueryWrapper<>();
            regionQueryWrapper.lambda().ge(Region::getLevel,4).like(Region::getName,areaName);
            List<Region> areaList = this.regionService.list(regionQueryWrapper);
            model.addAttribute("areaList", areaList);
        }
        return this.PREFIX + "bins_edit.html";
    }

    /**
     *清零
     */
    @RequestMapping({"/updateWeight"})
    @ResponseBody
    public Object binsWeight(String id){
        Bins bins = this.binsService.getById(id);
        bins.setManageUserId(0l);
        this.binsService.updateById(bins);
        return new SuccessResponseData();
    }
    
    @RequestMapping({ "/detail/{id}" })
    @ResponseBody
    public ResponseData detail(@PathVariable final String id) {
        final Bins bins = (Bins)this.binsService.getById((Serializable)id);
        return (ResponseData)ResponseData.success(bins);
    }
    
    @RequestMapping({ "/list" })
    @ResponseBody
    public Object list(final Bins binsQuery) {
        final QueryWrapper<Bins> binsQueryWrapper = ControllerUtil.createQuery(binsQuery, this.getHttpServletRequest());
        ShiroUser user = ShiroKit.getUser();
        boolean admin = ShiroKit.isAdmin();
        if(!admin){
            String avatar = StringUtils.defaultIfBlank(user.getAvatar(), IdUtil.fastSimpleUUID());
            binsQueryWrapper.lambda().in(Bins::getBinsNo, StrSpliter.splitTrim(avatar,",",true));
        }
        final Page<Bins> page = (Page<Bins>)LayuiPageFactory.defaultPage();
        final IPage<Bins> page2 = (IPage<Bins>)this.binsService.page((IPage)page, (Wrapper)binsQueryWrapper);
        List<Bins> records = page2.getRecords();
        if(records!=null && records.size()>0){
            DateTime nowTime = new DateTime();
            for(Bins bins:records){
                if(bins.getLastUpdateTime()==null){
                    bins.setStatus(1l);
                    this.binsService.updateById(bins);
                }else {
                    long between = nowTime.between(bins.getLastUpdateTime(), DateUnit.MINUTE);
                    if (between > 1) {//大于1分钟没有通讯
                        bins.setStatus(1l);
                        this.binsService.updateById(bins);
                    }
                }
            }
        }
        final List<BinsVO> binsVOList = EntityBind.bind(records, BinsVO.class);
        final List<Map<String, Object>> list = binsVOList.stream().map(bins -> BeanUtil.beanToMap(bins)).collect(Collectors.toList());
        page2.setRecords((List)new BinsWrapper(list).wrap());
        return LayuiPageFactory.createPageInfo(page2);
    }
    
    @RequestMapping({ "/addItem" })
    @ResponseBody
    public Object add(final Bins bins) {
        this.binsService.save(bins);
        return BinsController.SUCCESS_TIP;
    }
    
    @RequestMapping({ "/delete" })
    @ResponseBody
    public Object delete(@RequestParam final String id) {
        this.binsService.removeById((Serializable)id);
        return BinsController.SUCCESS_TIP;
    }
    
    @RequestMapping({ "/editItem" })
    @ResponseBody
    public Object update(final Bins bins) {
        String xsBeginTime = this.getPara("xsBeginTime");
        String xsEndTime = this.getPara("xsEndTime");
        String xsTime = this.getPara("xsTime");
        String xsTimeGap = this.getPara("xsTimeGap");
        int xsBeginTimeInt = NumberUtils.toInt(xsBeginTime);
        int xsEndTimeInt = NumberUtils.toInt(xsEndTime);
        int xsTimeGapInt = NumberUtils.toInt(xsTimeGap);
        int xsTimeHourGapInt = xsTimeGapInt/60;
        int xsTimeMinuteInt = xsTimeGapInt%60;
        if(xsTimeHourGapInt>0 && xsTimeMinuteInt>0){
            ErrorResponseData errorResponseData = new ErrorResponseData("隔间分钟大于1小时的，只能是小时的整数倍");
            return errorResponseData;
        }
        bins.setStatusDesc(xsBeginTime+"-"+xsEndTime+","+xsTime+","+xsTimeGap);
        String areaNext = this.getPara("areaNext");
        if(StrUtil.isNotBlank(areaNext)){
            bins.setArea(bins.getArea()+","+StrUtil.replace(areaNext,"- - - -",""));
        }
        this.binsService.updateById(bins);
        QuartzManager.removeJob(bins.getId()+"");
        QuartzManager.removeJob(bins.getId()+"_close");
        JobDataMap openJobDataMap = new JobDataMap();
        openJobDataMap.put("binsId",bins.getId());
        openJobDataMap.put("commandTag","sterilize_open");

        xsTimeHourGapInt = xsTimeHourGapInt<1?1:xsTimeHourGapInt;
        String hour = "";
        for(int i=xsBeginTimeInt;i<xsEndTimeInt+1;i=i+xsTimeHourGapInt){
            hour+=i+",";
        }
        hour = StrUtil.removeSuffix(hour,",");

        String minute = "";
        if(xsTimeMinuteInt>0){
            minute = "0/"+xsTimeMinuteInt;
        }else{
            minute = xsTimeMinuteInt+"";
        }

        String timeOpen = "0 "+minute+" "+hour+" * * ?";
        QuartzManager.addJob(bins.getId()+"",QuartzJob.class,timeOpen, openJobDataMap);

        JobDataMap closeJobDataMap = new JobDataMap();
        closeJobDataMap.put("binsId",bins.getId());
        closeJobDataMap.put("commandTag","sterilize_close");
        String timeClose = "0 "+xsTime+(xsTimeMinuteInt>0?"/"+xsTimeMinuteInt:"")+" "+hour+" * * ?";
        QuartzManager.addJob(bins.getId()+"_close",QuartzJob.class,timeClose, closeJobDataMap);
        //QuartzManager.startJobs();



        return BinsController.SUCCESS_TIP;
    }
    
    @RequestMapping(value = { "/delItems" }, method = { RequestMethod.POST })
    @ResponseBody
    public Object delItem(@RequestBody final String[] ids) {
        this.binsService.removeByIds((Collection)Arrays.asList(ids));
        return BinsController.SUCCESS_TIP;
    }
    
    @RequestMapping({ "/show" })
    public Object show(final String id, final Model model) {
        final Bins bins = (Bins)this.binsService.getById((Serializable)id);
        final Map map = BeanUtil.beanToMap(bins);
        model.addAttribute("bins", new BinsWrapper(map).wrap());
        return this.PREFIX + "bins_show.html";
    }

    @RequestMapping("/createQrcode")
    @ResponseBody
    public Object createQrcode(Long id){
        Bins bins = this.binsService.getById(id);
        File qrcodeSaveFile = null;
        String qrcodeImgPath = bins.getQrcodeImg();
        String qrcodeWebroot = "/upload/qrcode";
        final String qrcodeRootPath = ToolUtil.getWebRootPath(qrcodeWebroot);
        if (StringUtils.isNotBlank(qrcodeImgPath)) {
            qrcodeSaveFile = new File(qrcodeRootPath, qrcodeImgPath);
            if (!qrcodeSaveFile.exists()) {
                qrcodeImgPath = null;
            }
        }
        if (StringUtils.isBlank(qrcodeImgPath)) {
            if (StringUtils.isBlank(bins.getQrcodeUrl())) {
                if (this.wxMpService.switchover(WxUtils.getDefaultMp())) {
                    final WxMpQrCodeTicket wxMpQrCodeTicket;
                    try {
                        wxMpQrCodeTicket = this.wxMpService.getQrcodeService().qrCodeCreateLastTicket(bins.getId().toString());
                        bins.setQrcodeTicket(wxMpQrCodeTicket.getTicket());
                        bins.setQrcodeUrl(wxMpQrCodeTicket.getUrl());
                        qrcodeImgPath = UUID.randomUUID().toString() + ".jpg";
                        bins.setQrcodeImg(qrcodeImgPath);
                        final byte[] qrcode = QrcodeUtils.createQrcode(wxMpQrCodeTicket.getUrl(), 342, (File)null);
                        qrcodeSaveFile = new File(ToolUtil.getWebRootPath(qrcodeWebroot), qrcodeImgPath);
                        IOUtils.write(qrcode, new FileOutputStream(qrcodeSaveFile));
                        bins.insertOrUpdate();
                        //return new SuccessResponseData(qrcodeWebroot+"/"+qrcodeSaveFile.getName());
                    } catch (WxErrorException | IOException e) {
                        e.printStackTrace();
                    }
                }


            }

        }
        return new SuccessResponseData(qrcodeWebroot+"/"+qrcodeImgPath);
    }

    @RequestMapping("/bannerList")
    public Object bannerList(Model model){
        String imgRoot =ControllerUtil.getRealPath("/upload/img");
        List<String> imgNameList = FileUtil.listFileNames(imgRoot);
        List<String> imgWebPathList = new ArrayList<>();
        imgNameList.forEach(imgName->{
            imgWebPathList.add("/upload/img/"+imgName);
        });
        model.addAttribute("imgWebPathList",imgWebPathList);

        Map<String,String> imgMap = new HashMap<>();
        List<Bins> binsList = this.binsService.list();
        model.addAttribute("binsList",binsList);
        binsList.stream().forEach(bins->{
            String banners = bins.getBanners();
            if(StringUtils.isNotBlank(banners)) {
                String[] bannerArr = banners.split(",");
                for (String banner : bannerArr) {
                    Long binId = bins.getId();
                    String imgBins = StringUtils.join(ObjectUtil.defaultIfNull(imgMap.get(banner), ""), ",", binId);
                    imgMap.put(banner, imgBins);
                }
            }
        });
        model.addAttribute("imgMap",imgMap);
        return this.PREFIX + "banner_list.html";
    }
    @RequestMapping("/uploadBanner")
    public Object uploadBanner(Model model){
        final HttpServletRequest request = this.getHttpServletRequest();
        final String header = request.getHeader("content-type");
        if (StringUtils.containsIgnoreCase((CharSequence)header, (CharSequence)"multipart/form-data")) {
            final StandardServletMultipartResolver resolver = new StandardServletMultipartResolver();
            final MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(request);
            final Map<String, MultipartFile> fileMap = (Map<String, MultipartFile>)multipartRequest.getFileMap();
            final boolean file1 = fileMap.containsKey("file");
            if (file1) {
                final MultipartFile file2 = multipartRequest.getFile("file");
                try {
                    if (file2.getSize()>0) {
                        final String name = file2.getOriginalFilename();
                        final InputStream inputStream = file2.getInputStream();
                        String fileName = ControllerUtil.saveFile("/upload/img", inputStream, name);
                        SuccessResponseData successResponseData = new SuccessResponseData();
                        successResponseData.setMessage("上传成功，文件名为："+fileName);
                        model.addAttribute("response", successResponseData);
                    }else{
                        model.addAttribute("response",new ErrorResponseData("请选择需要上传的图片或视屏。"));
                    }

                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

        return "/common/msg.html";
    }
    @RequestMapping("/delBanner")
    @ResponseBody
    public Object delBanner(String path){
        String imgRoot = ControllerUtil.getRealPath("/");
        String imgWebRoot = ToolUtil.getWebRootPath("/");
        if(StringUtils.endsWithAny(path.toLowerCase(),"png","jpg","bmp","gif","jpeg","mp4")) {
            File imgFile = new File(imgRoot, path);
            imgFile.delete();
            System.out.println(imgFile.getAbsolutePath());
            File imgWebFile = new File(imgWebRoot,path);
            System.out.println(imgWebFile.getAbsolutePath());
            imgWebFile.delete();
        }else{
            return new ErrorResponseData("只能删除图片文件");
        }

        return new SuccessResponseData();
    }
    @RequestMapping("/bindBins")
    @ResponseBody
    public Object bindBins(String imgAndBins){
        if(StringUtils.isNotBlank(imgAndBins)){
            String[] imgAndBinsInfos = imgAndBins.split(",");
            if(ObjectUtil.length(imgAndBinsInfos)==3){
                Boolean checked = Convert.toBool(imgAndBinsInfos[2]);
                Long binsId = Convert.toLong(imgAndBinsInfos[1]);
                if(checked==null || binsId==null){
                    return new ErrorResponseData("数据格式不正确！");
                }
                Bins bins = this.binsService.getById(binsId);
                String banners = StringUtils.defaultIfBlank(bins.getBanners(),"");
                if(checked){
                    banners = StringUtils.join(banners,",",imgAndBinsInfos[0]);
                }else{
                    banners = banners.replace(imgAndBinsInfos[0],"").replaceAll(",+",",");
                }
                bins.setBanners(banners);
                bins.updateById();
                return new SuccessResponseData();
            }else{
                return new ErrorResponseData("数据格式不正确");
            }
        }else{
            return new ErrorResponseData("数据不能为空！");
        }
    }

    @RequestMapping("/jifenConfig")
    public String jifenConfig(Model model){
        Dict dict = DictUtils.me().getDict("jifen::jifen");
        model.addAttribute("dict",dict);
        return this.PREFIX+"jifen_config.html";
    }
    @RequestMapping("/jifen")
    @ResponseBody
    public Object jifen(String jifen){
        Dict dict = DictUtils.me().getDict("jifen::jifen");
        dict.setDescription(jifen);
        this.dictService.updateById(dict);
        return new SuccessResponseData();
    }

    @RequestMapping("/emptyBinWeightConfig")
    public String emptyBinWeightConfig(Model model){
        Dict dict = DictUtils.me().getDict("empty_bins_weight::weight");
        model.addAttribute("dict",dict);
        return this.PREFIX+"empty_bins_weight.html";
    }
    @RequestMapping("/saveEmptyBinWeight")
    @ResponseBody
    public Object saveEmptyBinWeight(String binWeight){
        Dict dict = DictUtils.me().getDict("empty_bins_weight::weight");
        dict.setDescription(binWeight);
        this.dictService.updateById(dict);
        return new SuccessResponseData();
    }

}
